# -*- coding: utf-8 -*-
"""
动画生成步骤
根据场景代码生成完整的Manim动画
"""

import json
import logging
from pathlib import Path
from typing import Dict, Any, List, Optional

from ..step_base import BaseStep, StepResult

logger = logging.getLogger(__name__)


class GenerateAnimationsStep(BaseStep):
    """动画生成步骤"""

    name = "generate_animations"
    description = "生成完整Manim动画"
    required_inputs = ["scene_files"]
    optional_inputs = ["animation_configs", "quality"]
    produces_outputs = ["animation_files"]

    def __init__(
        self,
        output_dir: Path,
        scene_files: Optional[List[Path]] = None,
        animation_configs: Optional[List[Dict[str, Any]]] = None,
        quality: str = "standard",
        **kwargs,
    ):
        """
        初始化步骤

        Args:
            output_dir: 输出目录
            scene_files: 场景文件列表
            animation_configs: 动画配置列表
            quality: 质量设置
        """
        super().__init__(output_dir, **kwargs)
        self.scene_files = scene_files or []
        self.animation_configs = animation_configs or []
        self.quality = quality

        # Manim配置
        self.manim_config = {
            "preview": "standard",
            "quality": "m",
            "frame_rate": 30,
            "pixel_width": 1920,
            "pixel_height": 1080,
        }

    def validate_inputs(self) -> tuple[bool, list[str]]:
        """验证输入"""
        errors = []

        if not self.scene_files:
            errors.append("No scene files provided")

        if not isinstance(self.scene_files, list):
            errors.append("Scene files must be a list")

        if self.quality not in ["preview", "standard", "high", "ultra"]:
            errors.append(f"Invalid quality setting: {self.quality}")

        return len(errors) == 0, errors

    def run(self) -> StepResult:
        """执行步骤"""
        try:
            self.report_progress(0, "Starting animation generation")

            animation_files = []

            # 生成每个场景的动画
            for i, scene_file in enumerate(self.scene_files):
                self.report_progress(
                    int((i / len(self.scene_files)) * 70),
                    f"Generating animation {i+1}/{len(self.scene_files)}"
                )

                animation_file = self._generate_animation(scene_file, i)
                animation_files.append(animation_file)

            # 生成主场景
            self.report_progress(80, "Creating main scene")

            main_scene_file = self._create_main_scene(animation_files)

            # 保存配置
            self.report_progress(90, "Saving animation configuration")

            self._save_configs(animation_files, main_scene_file)

            # 完成
            self.report_progress(100, "Animations generated successfully")

            return StepResult(
                success=True,
                message="Animations generated successfully",
                data={
                    "total_animations": len(animation_files),
                    "main_scene": str(main_scene_file),
                    "quality": self.quality,
                },
                output_files=[
                    self.output_dir / "animation_config.json",
                    main_scene_file,
                ] + animation_files,
            )

        except Exception as e:
            logger.exception("Failed to generate animations")
            return StepResult(
                success=False,
                message=f"Failed to generate animations: {str(e)}",
            )

    def _generate_animation(self, scene_file: Path, index: int) -> Path:
        """
        生成单个动画

        Args:
            scene_file: 场景文件
            index: 索引

        Returns:
            动画文件路径
        """
        # 检查场景文件
        if not scene_file.exists():
            raise FileNotFoundError(f"Scene file not found: {scene_file}")

        # 模拟动画生成
        # 在实际实现中，这里应该调用Manim命令
        # 例如：subprocess.run(["manim", "-pqm", scene_file, ...])

        animation_file = self.output_dir / f"animation_{index:03d}.mp4"

        # 创建空的动画文件（占位符）
        animation_file.touch()

        logger.info(f"Simulated animation generation for: {scene_file.name}")

        return animation_file

    def _create_main_scene(self, animation_files: List[Path]) -> Path:
        """
        创建主场景

        Args:
            animation_files: 动画文件列表

        Returns:
            主场景文件路径
        """
        main_scene_file = self.output_dir / "main_scene.py"

        # 生成主场景代码
        main_code = self._generate_main_scene_code(animation_files)

        with open(main_scene_file, "w", encoding="utf-8") as f:
            f.write(main_code)

        return main_scene_file

    def _generate_main_scene_code(self, animation_files: List[Path]) -> str:
        """
        生成主场景代码

        Args:
            animation_files: 动画文件列表

        Returns:
            Python代码
        """
        # 生成导入动画的代码
        animation_imports = []
        animation_objects = []

        for i, _ in enumerate(animation_files):
            animation_imports.append(f"from animation_{i:03d} import Animation{i:03d}")
            animation_objects.append(f"Animation{i:03d}()")

        # 生成主场景类
        code = f'''# -*- coding: utf-8 -*-
"""
主场景 - 组合所有动画
"""

from manim import *
import numpy as np

# 导入各个场景
{chr(10).join(animation_imports)}

class MainScene(Scene):
    """主场景 - 组合所有动画"""

    def construct(self):
        """构建主场景"""
        # 场景列表
        animations = [
            {chr(10).join([f"            {obj}," for obj in animation_objects])}
        ]

        # 逐个播放场景
        for i, anim_scene in enumerate(animations):
            # 创建场景实例
            scene = anim_scene
            scene.construct()

            # 播放动画
            self.play(scene)

            # 场景间隔
            if i < len(animations) - 1:
                self.wait(1.0)  # 1秒间隔

    def play_scene(self, scene_class):
        """播放指定场景"""
        scene = scene_class()
        scene.construct()
        self.play(scene)

class VideoScene(Scene):
    """视频场景 - 包含视频播放"""

    def __init__(self, video_files=None):
        super().__init__()
        self.video_files = video_files or []

    def construct(self):
        """构建场景"""
        for video_file in self.video_files:
            # 添加视频播放逻辑
            # 注意：Manim原生不支持视频播放，这里仅作为示例
            pass
'''

        return code

    def _save_configs(self, animation_files: List[Path], main_scene_file: Path):
        """
        保存配置

        Args:
            animation_files: 动画文件列表
            main_scene_file: 主场景文件
        """
        # 保存动画配置
        config = {
            "quality": self.quality,
            "manim_config": self.manim_config,
            "total_animations": len(animation_files),
            "animation_files": [str(f) for f in animation_files],
            "main_scene": str(main_scene_file),
        }

        with open(self.output_dir / "animation_config.json", "w", encoding="utf-8") as f:
            json.dump(config, f, indent=2, ensure_ascii=False)

    def get_manim_command(self) -> List[str]:
        """
        获取Manim命令

        Returns:
            Manim命令列表
        """
        # 质量映射
        quality_map = {
            "preview": "l",
            "standard": "m",
            "high": "h",
            "ultra": "k",
        }

        # 构建命令
        cmd = [
            "manim",
            f"-{quality_map.get(self.quality, 'm')}",  # 质量参数
            "--disable_caching",  # 禁用缓存
            "--output_file", str(self.output_dir / "output"),
        ]

        return cmd
